HI,大家好!因為之後會提到建構器間的繼承,所以在那之前先提一下constructor
這個特性的用途,這個特性在前兩篇的[筆記][JavaScript]使用建構器創造實體物件和[筆記][JavaScript]原型(prototype)在JavaScript中的兩種意思都有稍微提過,讓我們用這一篇文章再來加深一些印象。
一般來說,每個函式都會有一個原型物件function.prototype
,而他的特性constructor
會指向函式自己,以下例子:
//宣告一個空函式
function Func(){};
//去判斷他原型中的constructor特性
Func.prototype.constructor; //會回傳func本身
//拿來和函式本身比較
Func === Func.prototype.constructor; //會回傳true
好,再來就像之前說的,使用建構器創造出來的實體物件也會有一個constructor
特性,這時候的constructor
也會指向建構器本身,以下例子:
//宣告一個空函式用來當建構器使用
function Func(){};
//使用該建構器建構一個實體物件
var obj = new Func();
//來試著判斷實體物件中的constructor特性
obj.constructor; //會回傳func本身
//接著直接比較看看
obj.constructor === Func; //會回傳true
接著我們統整一下上述的觀念,在一個建構器Func
中Func.prototype.constructor;
和他建構出來的實體物件的constructor
特性都會指向Func
本身,所以我們可以用一個實體物件來建構出有相同建構器的實體物件,以下例子:
//宣告一個空函式用來當建構器使用
function Func(){};
//使用該建構器建構一個實體物件
var objA = new Func();
//經過上面的例子我們可以知道objA.constructor會等於建構器本身
Func === objA.constructor; //回傳true
//使用objA來建立一個擁有相同建構器的實體物件
var objB = new objA.constructor();
//用instanceof判斷是否為建構器Func的實體物件
objB instanceof Func; //回傳true
另外順便提一下建構器中的prototype
特性,通常每個函式都會有該特性,而且我們不會去取代這個特性原本有的內容(例如constructor
),而是在該特性中建立新的方法。以下範例:
//宣告一個空函式
function Func1(){};
//通常是不會去取代他的prototype,就像以下這樣
Func1.prototype = {
writeThis:function(){
console.log(this);
},
};
//為了避免蓋掉prototype,所以我們會在原本的prototype中建立方法
//宣告一個空函式
function Func2(){};
//在原本的prototype中新增方法
Func2.prototype.writeThis = function(){
console.log(this);
};
以上例子的技巧可以使用在必須處理某個建構器的實體,並且想要建立出和某個實體相同的方法來說很方便,更進一步可以把該方法寫進建構器的prototype中來使用:
//宣告一個空函式來當建構器使用
function Func(){};
//在該建構器的prototype建立一個方法特性
Func.prototype.copyObj = function(){
return new this.constructor();
};
//先建構一個實體物件
var objA = new Func();
//使用該實體物件繼承來的copyObj方法來建構第二個有同樣建構器的實體物件
var objB = objA.copyObj();
//最後來判斷他是否為建構器Func的實體物件
objB instanceof Func; //回傳true
以上是對constructor特性的一些說明和應用,如果有說明錯誤或不明白的地方,麻煩再留言告知我,我會盡速改正!!
過度依賴 constructor
可能不太好。
就像文章中所講的 constructor
是可以被更改的,且也是可能發生的情境,
例如在 ES5 前的繼承是使用以下方式來實作:
Child.prototype = Object.create(Parent.prototype);
此時如果忘記手動修復 constructor
的話,Child.prototype.constructor
就會是 Parent
。
因此應該盡量避免對 constructor
操作,若要檢查型別的話,使用 instanceOf
、Object.isPrototypeOf
甚至是 Object.getPrototypeOf
等函式都會是比較安全的。不過發現這點其實大大之前也提過呢!
對,感謝大大的補充!!
因為這篇文章想說提一下constructor
能夠做到的事情,卻忘了提醒大家該注意的事情,真的非常抱歉